/**
 * Copyright (c) 2006-2020, zwl
 * 
 * description  事件框架
 * 
 * Change Logs:
 * Date             Author         Notes
 * 2021-01-13       Zwl             创建
 * 
 */
#include "EntTypeFramework.h"

/* 事件分配计数 */
static etf_event_ev_t                           last_event          = 0;
/* 容器事件类型对象 */
static struct etf_object_information *          event_information   = ETF_NULL;
/* 最大事件数量 */
static struct etf_event                         events[ETF_EVENT_NUM_MAX];

/**
 *  事件框架初始化
 *
 *@param :
 *
 *@return:
 *
 *@note  : 
 *
 *
 */
void etf_event_module_init(void){

    etf_uint16_t                    i;

    event_information                               = etf_object_get_information(ETF_Object_Class_Event);
    ETF_IN_ASSERT(ETF_NULL != event_information);
    for(i = 0; i < ETF_EVENT_NUM_MAX; i++){
        events[i].data                              = ETF_NULL;
        events[i].p                                 = ETF_NULL;
        events[i].ev                                = ETF_PROCESS_EVENT_NONE;
        etf_object_init(&(events[i].parent), ETF_Object_Class_Event, ETF_NULL);
    }
}

/**
 * 事件分配
 *
 *@param :
 *
 *@return: ETF_PROCESS_EVENT_NONE：分配失败；其他：时间值；
 *
 *@note  : 
 *
 *
 */
etf_event_ev_t etf_event_alloc(void){

    if(ETF_PROCESS_EVENT_NONE <= last_event){
        return ETF_PROCESS_EVENT_NONE;
    } else {
        last_event++;
    }
    
    return last_event;
}

/**
 * 投递事件（异步）
 *
 *@param : p    ：事件关联的处理过程；
 *         ev   ：事件值；
 *         data ：事件数据；
 *
 *@return: 结果
 *
 *@note  : 
 *
 *
 */
etf_err_t etf_event_post(etf_event_fun_t p, etf_event_ev_t ev, etf_event_data_t data){

    struct etf_object *                     object;
    struct etf_list_node *                  node;
    struct etf_object_information *         information;

    ETF_IN_ASSERT(ETF_NULL != event_information);
    /* 在对象容器中查找到相应类型对象的链表头 */
    information                                     = event_information;
    /* 空闲的事件列表是否为空 */
    if(etf_list_isempty( &(information->object_suspend_list) )){
        /* 没有空闲的事件列表空间来存放事件 */
        return (-ETF_EEMPTY);
    }
    
    ETF_IRQ_DISABLE();

    node                                            = information->object_suspend_list.next;

    /* 获取节点对象 */
    object                                          = etf_list_entry(node, struct etf_object, list);

    /* 没有插入到任何链表中  */
    if(ETF_Object_list_state_null == object->state){
        ETF_IRQ_ENABLE();
        return (-ETF_ERROR);
    }    

    /* 删除节点 */
    etf_object_detach(object);
    
    ETF_IRQ_ENABLE();
    
    /* 设置事件节点信息 */
    ((etf_event_t)object)->ev                       = ev;
    ((etf_event_t)object)->data                     = data;
    ((etf_event_t)object)->p                        = p;
    
    /* 插入到运行链表中,链表尾 */
    ETF_LIST_INSERT_BEFORE_RUN_LIST(information, object);


    return ETF_EOK;
}

/**
 * 投递事件（同步）
 *
 *@param : p    ：事件关联的处理过程；
 *         ev   ：事件值；
 *         data ：事件数据；
 *
 *@return: 结果；
 *
 *@note  : 
 *
 *
 */
void etf_event_synch(etf_event_fun_t p, etf_event_ev_t ev, etf_event_data_t data){

#if ETF_COROUTINE_EN
    struct etf_co_tcb *                     caller;

    /* 保存当前任务 */
    caller                                          = etf_process_current;

    /* 处理事件 */
    call_process(p, ev, data);
    
    /* 恢复当前任务 */
    etf_process_current                             = caller;
#else

    p(ev, data);

#endif

}

/**
 *  事件运行处理
 *
 *@param :
 *
 *@return: 是否还有处理请求
 *
 *@note  : 
 *
 *
 */
etf_uint32_t etf_event_run(void){

#if ETF_COROUTINE_EN
    struct etf_co_tcb *                     caller;
#endif

    struct etf_object *                     object;
    struct etf_list_node *                  node;
    struct etf_object_information *         information;
    
    ETF_IN_ASSERT(ETF_NULL != event_information);
    /* 在对象容器中查找到相应类型对象的链表头 */
    information                                     = event_information;
    
    /* 运行的事件列表是否为空 */
    if(etf_list_isempty( &(information->object_run_list) )){
        /* 没有事件需要处理 */
        return (0);
    }
    
    ETF_IRQ_DISABLE();

    node                                            = information->object_run_list.next;

    /* 获取节点对象 */
    object                                          = etf_list_entry(node, struct etf_object, list);

    /* 没有插入到任何链表中  */
//    if(ETF_Object_list_state_run_list != object->state){
//        ETF_IRQ_ENABLE();
//        return (-ETF_ERROR);
//    }    

    /* 删除节点 */
    etf_object_detach(object);
    ETF_IRQ_ENABLE();
    
    /* 处理事件 */
    if( ETF_NULL != ((etf_event_t)object)->p){
#if ETF_COROUTINE_EN

    /* 保存当前任务 */
    caller                                          = etf_process_current;

    /* 处理事件 */
    call_process(((etf_event_t)object)->p, ((etf_event_t)object)->ev, ((etf_event_t)object)->data);
    
    /* 恢复当前任务 */
    etf_process_current                             = caller;
#else

    ((etf_event_t)object)->p(((etf_event_t)object)->ev, ((etf_event_t)object)->data);

#endif
    }
    
    ((etf_event_t)object)->data                     = ETF_NULL;
    ((etf_event_t)object)->p                        = ETF_NULL;
    ((etf_event_t)object)->ev                       = ETF_PROCESS_EVENT_NONE;
    /* 插入到挂起链表中,链表尾 */
    ETF_LIST_INSERT_BEFORE_SUSPEND_LIST(information, object);

    if(etf_list_isempty( &(information->object_run_list) )){
        /* 没有事件需要处理 */
        return (0);
    } else {
        /* 还有事件需要处理 */
        return 1;
    }
}





